﻿/*
-----------------------------------------------------------------------------
This source file is part of Cell Cloud.

Copyright (c) 2009-2012 Cell Cloud Team (cellcloudproject@gmail.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#ifndef CellSQLiteResultSet_h
#define CellSQLiteResultSet_h

#include "CellPrerequisites.h"
#include "CellResultSet.h"

namespace cell
{
/** \addtogroup Core
 *  @{
 */
/** \addtogroup General
 *  @{
 */

/** Meta data
*/
class _CellExport SQLiteMetaData : public StorageAlloc
{
public:
	/**
	*/
	SQLiteMetaData(void);

	/**
	*/
	virtual ~SQLiteMetaData(void);

private:
	typedef HashMap<String, int> ColumnIndexMap;
	ColumnIndexMap mColumnIndex;
};


/**
*/
class _CellExport SQLiteResultSet : public ResultSet, public StorageAlloc
{
public:
	/**
	*/
	SQLiteResultSet(void);

	/**
	*/
	virtual ~SQLiteResultSet(void);

public:
	/**
	*/
	bool absolute(int cursor);

	/**
	*/
	bool relative(int cursor);

	/**
	*/
	bool first(void);

	/**
	*/
	bool last(void);

	/**
	*/
	bool next(void);

	/**
	*/
	bool previous(void);

	/**
	*/
	bool isFirst(void);

	/**
	*/
	bool isLast(void);

	/**
	*/
	char getChar(int index);

	/**
	*/
	char getChar(const String& label);

	/**
	*/
	int getInt(int index);

	/**
	*/
	int getInt(const String& label);

	/**
	*/
	long getLong(int index);

	/**
	*/
	long getLong(const String& label);

	/**
	*/
	int64 getInt64(int index);

	/**
	*/
	int64 getInt64(const String& label);

	/**
	*/
	String getString(int index);

	/**
	*/
	String getString(const String& label);

	/**
	*/
	bool getBool(int index);

	/**
	*/
	bool getBool(const String& label);

	/**
	*/
	int getRaw(const String& label, char* dst, int offset, int length);

	/**
	*/
	int64 getRaw(const String& label, char* dst, int64 offset, int64 length);

	/**
	*/
	void updateChar(int index, char value);

	/**
	*/
	void updateChar(const String& label, char value);

	/**
	*/
	void updateInt(int index, int value);

	/**
	*/
	void updateInt(const String& label, int value);

	/**
	*/
	void updateLong(int index, long value);

	/**
	*/
	void updateLong(const String& label, long value);

	/**
	*/
	void updateInt64(int index, int64 value);

	/**
	*/
	void updateInt64(const String& label, int64 value);

	/**
	*/
	void updateString(int index, const String& value);

	/**
	*/
	void updateString(const String& label, const String& value);

	/**
	*/
	void updateBool(int index, bool value);

	/**
	*/
	void updateBool(const String& label, bool value);

	/**
	*/
	void updateRaw(const String& label, char* src, int offset, int length);

	/**
	*/
	void updateRaw(const String& label, char* src, int64 offset, int64 length);

protected:
	/**
	*/
	class _CellPrivate RowSet : public StorageAlloc
	{
	public:
		RowSet(void);
		virtual ~RowSet(void);

	public:
		/**
		*/
		void set(int columnIndex, const String& value);

		/**
		*/
		const String& get(int columnIndex) const;

	private:
		typedef HashMap<int, String> ColumnValueMap;
		ColumnValueMap mValues;
	};

	typedef HashMap<int, RowSet*> RowSetMap;

	/**
	*/
	void beginAdd(void);

	/**
	*/
	void endAdd(void);

	/**
	*/
	void addDataByColumn(int columnIndex, char* column, char* value);

private:
	/**
	*/
	RowSet* getRowSet(int index);

private:
	SQLiteMetaData mMetaData;

	int mRowCursor;
	RowSet* mCurrentRow;
	RowSetMap mRowSets;

	int mMaxRowNum;

	friend int sqlite_callback(void* resultset, int ncols, char** values, char** headers);
};

/** @} */
/** @} */
} // end namespace cell

#endif // CellSQLiteResultSet_h
